#pragma once
#include<iostream>
using namespace std;
#include<assert.h>
namespace MoYu
{
	class string
	{
	#define npos -1
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		string();
		string(const string& str);
		string(const string& str, size_t pos, size_t len = npos);
		string(const char* s);
		string(const char* s, size_t n);
		string(size_t n, char c);
		template <class InputIterator>
		string(InputIterator first, InputIterator last)
			:_s(new char[4])
			, _size(0)
			, _capacity(4)
		{
			_s[0] = '\0';
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}
		string(initializer_list<char> il);
		string(string&& str) noexcept;


		string& operator= (string&& str) noexcept;
		string& operator= (const string& str);

		iterator begin() noexcept;
		const_iterator begin() const noexcept;

		iterator end() noexcept;
		const_iterator end() const noexcept;

		size_t size() const noexcept;

		void resize(size_t n);
		void resize(size_t n, char c);

		size_t capacity() const noexcept;

		void reserve(size_t n = 0);

		void clear() noexcept;

		bool empty() const noexcept;


		char& operator[] (size_t pos);
		const char& operator[] (size_t pos) const;


		string& operator+= (const string& str);
		string& operator+= (const char* s);
		string& operator+= (char c);
		string& operator+= (initializer_list<char> il);


		void push_back(char c);


		string& insert(size_t pos, const string& str);
		string& insert(size_t pos, const string& str, size_t subpos, size_t sublen);
		string& insert(size_t pos, const char* s);
		string& insert(size_t pos, const char* s, size_t n);
		string& insert(size_t pos, size_t n, char c);
		iterator insert(const_iterator p, size_t n, char c);
		//iterator insert(const_iterator p, char c);
		//template <class InputIterator>
		//iterator insert(iterator p, InputIterator first, InputIterator last);
		//string& insert(const_iterator p, initializer_list<char> il);


		string& erase(size_t pos = 0, size_t len = npos);
		iterator erase(const_iterator p);
		iterator erase(const_iterator first, const_iterator last);



		size_t find(const string& str, size_t pos = 0) const noexcept;

		size_t find(const char* s, size_t pos = 0) const;

		size_t find(char c, size_t pos = 0) const noexcept;


		string substr(size_t pos = 0, size_t len = npos) const;

		void swap(string& s);

		void swap(string&& s);

		~string();

		typedef char* iterator;
		typedef const char* const_iterator;
		bool operator<(const string& s);
		bool operator==(const string& s);
		bool operator>(const string& s);
		bool operator<=(const string& s);
		bool operator>=(const string& s);
		bool operator!=(const string& s);
		friend istream& operator>>(istream& in, string& str);
		friend ostream& operator<<(ostream& out, string& str);


		friend ostream& operator<<(ostream& out, const string& str);
	private:
		char* _s;
		size_t _size;
		size_t _capacity;
	};

}